package cn.pconline.autoclub.web.wap;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.velocity.VelocityContext;
import org.gelivable.dao.GeliDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import cn.pconline.autoclub.config.SystemConfig;
import cn.pconline.autoclub.entity.Club;
import cn.pconline.autoclub.entity.ClubMember;
import cn.pconline.autoclub.entity.InviteJoin;
import cn.pconline.autoclub.entity.InviteMember;
import cn.pconline.autoclub.entity.User;
import cn.pconline.autoclub.service.ClubService;
import cn.pconline.autoclub.service.IntfService;
import cn.pconline.autoclub.service.InviteJoinService;
import cn.pconline.autoclub.service.InviteMemberService;
import cn.pconline.autoclub.service.MemberService;
import cn.pconline.autoclub.service.MessageService;
import cn.pconline.autoclub.service.UserForumService;
import cn.pconline.autoclub.service.UserService;
import cn.pconline.autoclub.util.EncodeUtils;
import cn.pconline.autoclub.util.JsonResult;
import cn.pconline.autoclub.util.Regex;
import cn.pconline.autoclub.util.TmplUtils;
import cn.pconline.autoclub.util.WebUtils;
import cn.pconline.autoclub.util.mail.MailSenderInfo;
import cn.pconline.autoclub.util.mail.SimpleMailSender;
import cn.pconline.autoclub.web.UserAuth;

import com.alibaba.fastjson.JSONObject;

@Controller
@RequestMapping(value = "/wap")
public class UserAction {

    @Autowired
    private UserService userService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private ClubService clubService;
    @Autowired
    private MessageService messageService;
    @Autowired
    private UserAuth userAuth;
    @Autowired
    private SystemConfig systemConfig;
    @Autowired
    private IntfService intfService;

    @Autowired
    private InviteJoinService inviteJoinService;
    @Autowired
    private InviteMemberService inviteMemberService;
    @Autowired
    private UserForumService userForumService;
    private static final Logger log = LoggerFactory.getLogger(UserAction.class);
    public static int NEW_MEMBER_COUNT = 9;
    private final static int DB_MAX_LENGTH = 255; //爱车最大长度

    /**
     * 一键邀请(加入)
     *
     * @param req
     * @param resp
     */
    @RequestMapping(value = "/member/inviteJoin.do", method = RequestMethod.POST)
    public void inviteJoinClub(HttpServletRequest req, HttpServletResponse resp) {
        WebUtils.setEncoding(req, resp);
        String code = WebUtils.param(req, "code", "");
        String nickName = WebUtils.param(req, "nickName", "");
        String telePhone = WebUtils.param(req, "telePhone", "");
        int gender = WebUtils.paramInt(req, "sex", User.MALE);
        long provinceId = WebUtils.paramLong(req, "provinceId", 0);
        String provinceName = WebUtils.param(req, "provinceName", "");
        long cityId = WebUtils.paramLong(req, "cityId", 0);
        String cityName = WebUtils.param(req, "cityName", "");
        int brandId = WebUtils.paramInt(req, "brandId", 0);
        int serialId = WebUtils.paramInt(req, "serialId", 0);
        if (StringUtils.isBlank(code)) {
            printWriter(resp, new JsonResult(JsonResult.STATUS_ERROR, "参数不对").toString());
            return;
        }
        InviteJoin inviteJoin = inviteJoinService.getInviteJoinByCode(code);
        if (inviteJoin == null) {
            printWriter(resp, new JsonResult(JsonResult.STATUS_ERROR, "邀请链接已过期").toString());
            return;
        }
        Club club = clubService.getValidClub(inviteJoin.getClubId());
        if (club == null) {
            printWriter(resp, new JsonResult(JsonResult.STATUS_ERROR, "邀请链接已过期").toString());
            return;
        }
        if (StringUtils.isBlank(nickName) || !nickName.matches("([a-zA-Z0-9_]|[^\\x00-\\xff])+")) {
            JSONObject obj = new JSONObject();
            obj.put("field", "nickname");
            obj.put("message", "昵称由1-16个字符(字母、数字或下划线)或1-8个中文组成");
            printWriter(resp, new JsonResult(JsonResult.STATUS_ILLEGAL_ARGUMENT, obj.toJSONString()).toString());
            return;
        }
        if (StringUtils.isBlank(telePhone) || !telePhone.matches(Regex.cellphone.value)) {
            JSONObject obj = new JSONObject();
            obj.put("field", "telephone");
            obj.put("message", "请输入正确的联系电话");
            printWriter(resp, new JsonResult(JsonResult.STATUS_ILLEGAL_ARGUMENT, obj.toJSONString()).toString());
            return;
        }
        if (provinceId <= 0 || cityId <= 0) {
            JSONObject obj = new JSONObject();
            obj.put("field", "area");
            obj.put("message", "请选择地区");
            printWriter(resp, new JsonResult(JsonResult.STATUS_ILLEGAL_ARGUMENT, obj.toJSONString()).toString());
            return;
        }
        //验证登录
        User user = userAuth.getUser(req, resp);
        if (!isLogin(user)) {
            printWriter(resp, new JsonResult(JsonResult.STATUS_ERROR, "请先登录").toString());
            return;
        }
        if (memberService.isClubMember(user.getUid(), club.getClubId())) {
            printWriter(resp, new JsonResult(JsonResult.STATUS_ERROR, "已经加入该车友会").toString());
            return;
        }
        //验证加入车友会个数
        int count = userService.updateJoinedClubCount(user);
        if (count >= NumberUtils.toInt(systemConfig.getJoinClubLimit(), 1)) {
            printWriter(resp, new JsonResult(JsonResult.STATUS_ERROR, "已经加入其他车友会,无法再加入该车友会").toString());
            return;
        }
        if (!memberService.findMemberApplication(user.getUid(), club.getClubId(), true).isEmpty()) {
            printWriter(resp, new JsonResult(JsonResult.STATUS_ERROR, "您已经提交申请加入，请等待会长审核").toString());
            return;
        }
        if (!memberService.listClubMemberByUser(user.getUid()).isEmpty() || !clubService.findByFounder(user.getUid(), true).isEmpty()) { //已经申请加入另一个车友会 或 已创建一个车友会待审核
            printWriter(resp, new JsonResult(JsonResult.STATUS_ERROR, "您只能申请或加入一个车友会").toString());
            return;
        }
        
        user.setNickname(nickName);
        user.setProvinceId(provinceId);
        user.setProvince(provinceName);
        user.setCityId(cityId);
        user.setCity(cityName);
         //更新车友会用户的爱车信息
        String carInfo = getCarInfo(req);
        user.setCarInfo(carInfo);
        userService.updateUser(user);
        
        long id = memberService.createMemberInfo(club.getClubId(), user, ClubMember.NON_ADMIN);
        if (id > 0) {
            //加入车友会之后，初始化车友圈
            userForumService.createIfNothing(user.getUid(), cityId, provinceId, serialId);
            
            User inviter = userService.findUser(inviteJoin.getCreateBy());
            User admin = new User();
            ClubMember admins = memberService.findAdminByClubId(club.getClubId());
            admin.setUid(admins.getUid());//只需要会长ID
            //更新邀请链接邀请人数
            inviteJoin.setInvitedCount(inviteJoin.getInvitedCount() + 1);
            inviteJoinService.updateInviteJoinCount(inviteJoin);
            //创建邀请记录
            InviteMember inviteMember = new InviteMember();
            inviteMember.setInviteId(inviteJoin.getInviteId());
            inviteMember.setUserId(user.getUid());
            inviteMember.setJoinAt(new Date());
            inviteMemberService.createInviteMember(inviteMember);
       


            Cookie c = new Cookie("isFirstJoin", "true");
            c.setPath("/");
            c.setDomain(".pcauto.com.cn");
            //     c.setMaxAge(10);
            resp.addCookie(c);
            JSONObject obj = new JSONObject();
            obj.put("status", JsonResult.STATUS_SUCCESS);
            obj.put("url", club.getClubUrl());
            obj.put("desc", "加入成功");
            printWriter(resp, obj.toJSONString());
            
            //当没选择市传省ID,都没选择不传
            long domicileId = cityId > 0 ? cityId : provinceId > 0 ? provinceId : 0;
            //同步个人资料到个人中心
            String commonSessionId = cn.pconline.passport2.util.WebUtils.getCookie(req, systemConfig.getUserSessionName());
            intfService.updateUserCenter(commonSessionId, null, nickName, gender, telePhone, null, null, domicileId, null);
            //同步爱车信息到个人中心
            if (brandId > 0 && serialId > 0) {
                intfService.checkBrandSerial(brandId, serialId, systemConfig.getUserSessionName(),
                        WebUtils.cookie(req, systemConfig.getUserSessionName()));
            }
            //发消息给会长
            messageService.send(admin, MessageService.INVITE_JOIN_CLUB_SUCCESS_MSG,
                    user.getUid(), user.getNickname(), inviter.getUid(), inviter.getNickname(), club.getClubUrl(), club.getName());
            //给加入会员发系统消息
            String msg = String.format(MessageService.INVITE_JOIN_APPLY_SUCCESS_MSG,messageService.assembleClubUrl(club.getClubUrl(), club.getName()));
            messageService.send(user.getUid(), msg);
            //发短信通知会员
            messageService.sendSMS(telePhone,user.getUid(), MessageService.APPLY_PASS_SMS, club.getName());              
	        //发邮件通知会员
            if( user.getEmail() != null && user.getEmail().matches(Regex.email.value)){
                String[] mailToAddress = {user.getEmail()} ;
                String subject = String.format(MessageService.APPLY_PASS_MAIL_SUBJECT, club.getName());
	    		VelocityContext velocityContext = new VelocityContext();
	    		velocityContext.put("nickName", user.getNickname());
	    		velocityContext.put("clubName", club.getName());
	    		velocityContext.put("clubUrl", club.getClubUrl());
	    	    velocityContext.put("ucRoot", systemConfig.getUcRoot());
	    		velocityContext.put("userId", user.getUid());
	    		velocityContext.put("root", systemConfig.getRoot());
	    		String content = TmplUtils.render(systemConfig.getDataPath() + File.separator, "applyPassMailTempate.html", velocityContext);
	    		MailSenderInfo mailInfo = SimpleMailSender.getSenderInfo(systemConfig.getMailServerHost(), systemConfig.getMailServerPort(),
            			    true, systemConfig.getMailPassWord(), systemConfig.getFromAddress(), mailToAddress, subject, content);
	    	    if(SimpleMailSender.sendHtmlMail(mailInfo)){
	    				 log.info("success to send mail for user[{}]", user.getUid());
	    			}else{
	    				 log.error("fail success to send mail for user[{}]", user.getUid());
	    			}
	            }
        }
    }
   
    /**
     * 获取请求中的爱车信息
     *
     * @param request
     * @return
     */
    private String getCarInfo(HttpServletRequest request) {
        String brand = WebUtils.paramTrim(request, "brandId", "");
        String serial = WebUtils.paramTrim(request, "serialId", "");
        String brandName = WebUtils.getAreaPlaceByReq(request, "brandName", "").trim();
        String serialName = WebUtils.paramTrim(request, "serialName", "");
        String carInfo = "";
        if(serial.startsWith("+")||brand.startsWith("+")){//忽略脏数据，正常不应该有这些数据
            return carInfo;
        }
        if(brandName.matches("^[A-Z] .*")){//如：A 奥迪 去掉前面的“A ”
            brandName=brandName.substring(2,brandName.length());
        }
        if (!brand.isEmpty() && !brand.equals("0") && !brandName.isEmpty()) {
            carInfo += brand + ";" + brandName + ";";
        }
        if (!serial.isEmpty() && !serial.equals("0") && !serialName.isEmpty()) {
            carInfo += serial + ";" + serialName + ";";
        }
        if (carInfo.endsWith(";")) {
            carInfo = carInfo.substring(0, carInfo.length() - 1);
        }
        if (carInfo.length() > DB_MAX_LENGTH) {
            return null;
        }
        return carInfo;
    }
    private boolean isLogin(User user) {
        if (user == null || user.getUid() == 0) {
            return false;
        }
        return true;
    }
    

    /**
     * 返回信息方法
     *
     * @param resp
     * @param json
     */
    private void printWriter(HttpServletResponse resp, String json) {
        printWriter(resp, json, "");
    }

    /**
     * 返回信息方法
     *
     * @param resp
     * @param json
     */
    private void printWriter(HttpServletResponse resp, String json, String callback) {
        callback = EncodeUtils.encodeForHTMLFilterNull(callback);
        try {
            PrintWriter out = resp.getWriter();
            if (StringUtils.isBlank(callback)) {
                out.println(json);
            } else {
                out.println(callback + "(" + json + ")");
            }
            out.flush();
            out.close();
        } catch (IOException ex) {
            log.error("返回信息方法异常！", ex);
        }
    }
}
